﻿
using System;
using System.Linq;
using System.Collections.Generic;

namespace Cheka.WinForm.Sample.Course
{
    public sealed class SemesterGrpPresenter
    {
        // ******************************************************************* //
        #region "member variables"

        private string m_fileName;

        /// <summary>
        /// all courses in the study plan, but grouped by a specific property
        /// which can be sememster, or, department
        /// </summary>
        private IDictionary<string, IList<Course>> m_courses;

        private ICourseView m_view;

        #endregion

        // ******************************************************************* //
        #region "constructor and destructor"

        public SemesterGrpPresenter(string fileName, ICourseView view)
        {
            m_fileName = fileName;
            m_view = view;

            // load m_courses
            m_courses = new Dictionary<string, IList<Course>>();

            StudyPlan plan = StudyPlan.Load(m_fileName);

            // !!! cannot use ILookup here, first because items returned by an index is an IEnumerable, not a concrete container
            // !!! and ILookup is readonly
            IEnumerable<IGrouping<string, Course>> grpsBySemester = plan.Courses.GroupBy(course => course.Semester);
            foreach (IGrouping<string, Course> grp in grpsBySemester)
            {
                m_courses.Add(grp.Key, grp.ToList());
            }
        }

        #endregion

        // ******************************************************************* //
        #region "course management"

        public IList<Course> GetCourses(string semester)
        {
            return m_courses[semester];
        }

        #endregion

        // ******************************************************************* //
        #region "UI operation"

        private void FillSemesters()
        {
            IList<string> grpNames = m_courses.Keys.ToList();
            m_view.FillGroupNames(grpNames);
        }

        public void OnLoad()
        {
            FillSemesters();
            OnCurSemesterChanged();
        }

        public void OnCurSemesterChanged()
        {
            IList<Course> courses = m_courses[m_view.CurrentGrpName];
            m_view.DisplayCourses(courses);
        }

        public void OnSave()
        {
            StudyPlan plan = new StudyPlan();
            IEnumerable<Course> courses = from kv in m_courses
                                          from course in kv.Value
                                          select course;
            foreach (Course course in courses)
                plan.AddCourse(course);

            StudyPlan.Save(m_fileName, plan);

            m_view.ShowMessage(string.Format("Total {0} courses saved", plan.Courses.Count.ToString()));
        }

        public void OnAddCourse(Course newCourse)
        {
            IList<Course> courses = null;
            if (!m_courses.TryGetValue(newCourse.Semester, out courses))
            {
                courses = new List<Course>();
                m_courses.Add(newCourse.Semester, courses);
                FillSemesters();
            }

            courses.Add(newCourse);
            m_view.CurrentGrpName = newCourse.Semester;
            OnCurSemesterChanged();

            m_view.ShowMessage("New course added.");
        }

        public void OnRemoveCourse(Course course)
        {
            IList<Course> courses = null;
            if (m_courses.TryGetValue(course.Semester, out courses))
            {
                // !!! below codes will always works
                // !!! whether Course override "object's Equal" or not
                // !!! due to data binding, the parameter to be removed just
                // !!! the same as the element contained in the list
                courses.Remove(course);
            }
            OnCurSemesterChanged();// re-binding
            m_view.ShowMessage("Course removed.");
        }

        #endregion
    }
}